<?php
/*
create table token (
	id int(10) private key auto_increment,
	name varchar(100) not null,
	value varchar(100) not null,
	expire int(10) not null
) type = MyISAM;

*/
define('XOOPS_TOKEN_VALID', 1);

define('XOOPS_TOKEN_INVALID', 10);
define('XOOPS_TOKEN_INVALID_NO_TOKEN', 11);
define('XOOPS_TOKEN_INVALID_NO_TOKEN_FORM', 12);
define('XOOPS_TOKEN_INVALID_NO_TOKEN_COOKIE', 13);
define('XOOPS_TOKEN_INVALID_UNMATCH_TOKEN', 14);
define('XOOPS_TOKEN_INVALID_TOKEN_NOT_FOUND', 15);
define('XOOPS_TOKEN_INVALID_ID', 20);
define('XOOPS_TOKEN_INVALID_REFERER', 30);
define('XOOPS_TOKEN_INTERNAL_ERROR', 99);

class XoopsToken {
	var $_name;
	var $_length;
	var $_id;
	var $_value;
	var $_table = '0123456789abcdefghijklmnopqrstuvwxyz';
	var $_expire;
	var $_current_time;
	
	function XoopsToken($name, $expire = 3600){
		$this->_length = 20;
		$this->_name = $name;
		$this->_id = 0;
		$this->_value = null;
		$this->_current_time = time();
		$expire_check = intval($expire);
		if($expire_check > 0){
			$this->_expire = $this->_current_time+$expire_check;
		}else{
			$this->_expire = $this->_current_time+3600;
		}
	}
	
	function delete(){
		global $xoopsDB;
		if($this->_id <= 0){
			return false;
		}
		$sql = sprintf("delete from %s where id = %u",
			$xoopsDB->prefix('token'),
			$this->_id);
		$xoopsDB->queryF($sql);
		return true;
	}
	
	function deleteExpired(){
		global $xoopsDB;
		if($this->_id <= 0){
			return false;
		}
		$sql = sprintf("delete from %s where expire > %u",
			$xoopsDB->prefix('token'),
			intval($this->_current_time));
		$xoopsDB->queryF($sql);
		return true;
	}
	
	function _load($value){
		global $xoopsDB;
		$value = trim($value);
		if(preg_match("/^([0-9]+)-([a-zA-Z0-9]*)/", $value, $m)){
			$id = intval($m[0]);
			if($id <= 0){
				return false;
			}
			$value = $m[1];
			if( (strlen($value) != $this->_length)){
				return false;
			}
			$sql = sprintf("select id, value, expire from %s where id=%u and name=%s and value=%s",
				$xoopsDB->prefix('token'),
				$id,
				$xoopsDB->quoteString($this->_name),
				$xoopsDB->quoteString($value));
			$rs = $xoopsDB->query($sql);
			if(!$rs){
				return false;
			}
			if(list($id, $value, $expire) = $this->_xoopsDB->fetchRow($rs)){
				if($this->_current_time > $expire){
					return false;
				}
				$this->_id = $id;
				$this->_value = $value;
				$this->_expire = $expire;
				return true;
			}
			return false;
		}
		return false;
	}
	
	function create(){
		global $xoopsDB;
		$this->_value = "";
		list(, $msec1) = explode(' ', microtime());
		list(, $msec2) = explode(' ', microtime());
		list(, $msec3) = explode(' ', microtime());
		list(, $msec4) = explode(' ', microtime());
		mt_srand(  ((int)$msec1 ) + ((int)$msec2 ) + ((int)$msec3 ) + ((int)$msec4 ) );
		for($i = 0; $i < $this->_length; $i++){
			$key = mt_rand(0, strlen($this->_table)-1);
			$this->_value .= $this->_table[$key];
		}
		$sql = sprintf(
			"insert into %s(id, name, value, expire) values(0, %s, %s, %u)",
			$xoopsDB->prefix("token"),
			$xoopsDB->quoteString($this->_name),
			$xoopsDB->quoteString($this->_value),
			$this->_current_time+$this->_expire);
		$xoopsDB->queryF($sql);
		$this->_id = $xoopsDB->getInsertId();
		
	}
	function getName(){
		return $this->_name;
	}
	function getId(){
		return $this->_id;
	}
	function getExpire(){
		if($this->_id != 0){
			return $this->_expire;
		}
		return null;
	}
	
	function getValue(){
		if($this->_id != 0){
			return $this->_id."-".$this->_value;
		}
		return null;
	}
	function getTokenHtml(){
		if($this->_id != 0){
			$result = sprintf('<input type="hidden" name="%s" value="%s" />',
				htmlspecialchars($this->_name),
				htmlspecialchars($this->_getValue()));
			return $result;
		}
		return null;
	}
	function sendTokenCookie($cookie_path = XOOPS_URL, $is_secure = 0){
		$domain = "";
		$path = "";
		$parsed_url = parse_url($cookie_path);
		$domain = $parsed_url['host'];
		$path = $parsed_url['path'];
		$is_secure = intval($is_secure);
		if( !($is_secure == 0) && !($is_secure == 1)){
			$is_secure = 0;
		}
		setcookie($this->_name, $this->_getValue(), $this->_expire, $path, $domain, $is_secure);
	}
	
	function _getToken(&$array){
		if(array_key_exists($this->_name, $array)){
			$result = $array[$this->_name];
			if (get_magic_quotes_gpc()) {
				$result =& stripslashes($result);
			}
			if(empty($result) || (strlen($result) == 0) ){
				return null;
			}
			return $result;
		}
		return null;
	}
	function checkToken($method = 'POST', $cookie_check = true, $referer_check = true){
		global $HTTP_POST_VARS, $HTTP_GET_VARS, $HTTP_COOKIE_VARS;
		if($referer_check && !xoops_refcheck()){
			return XOOPS_TOKEN_INVALID_REFERER;
		}
		$formValue = null;
		$checkVar = null;
		if('POST' == $method){
			$checkVar =& $HTTP_POST_VARS;
		}else if('GET' == $method){
			$checkVar =& $HTTP_GET_VARS;
		}else{
			return XOOPS_TOKEN_INTERNAL_ERROR;
		}
		$formValue = $this->__getToken($checkVar);
		if($formValue == null){
			return XOOPS_TOKEN_INVALID_NO_TOKEN_FORM;
		}
		
		if($cookie_check){
			$cookieIdValue = $this->__getToken($HTTP_COOKIE_VARS);
			if($cookieIdValue == null){
				return XOOPS_TOKEN_INVALID_NO_TOKEN_COOKIE;
			}else if($cookieIdValue != $formIdValue){
				return XOOPS_TOKEN_INVALID_UNMATCH_TOKEN;
			}
		}
		if(!$this->__load($formValue)){
			return XOOPS_TOKEN_INVALID_TOKEN_NOT_FOUND;
		}
		if($this->_getToken() != $formValue){
			return XOOPS_TOKEN_INVALID_UNMATCH_TOKEN;
		}
		return true;
	}

}
$val = "";
$table = "0123456789abcdefghijklmnopqrstuvwxyz";
list($msec1, $sec1) = explode(' ', microtime());
list($msec2, $sec2) = explode(' ', microtime());
list($msec3, $sec3) = explode(' ', microtime());
list($msec4, $sec4) = explode(' ', microtime());
$sal = ((float)$msec1 *100000) * ((float)$msec2 *100000) + ((float)$msec3 *100000) * ((float)$msec4 *100000);
mt_srand(  $sal );
for($i = 0; $i < 20; $i++){
	$key = mt_rand(0, strlen($table)-1);
	$val .= $table[$key];
}
echo $msec4."\n";
echo $sal."\n";
echo $val;
?>
